package com.example.score.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

@Slf4j
public class WxUtil {
    private static final String APPID = "wxc1988ee4eea27c09";
    private static final String APPSECRET = "7e2cdb5251dbc6cfe6696bb30a6070e8";
    //private static final String TEMPLATE_ID = "n4DY3_Nr-M3XEvFfXMbuYh359INSlrEL5LGz7rNJwhQ";
    private static final String TEMPLATE_ID = "ABE5xGsLqAAAkX3aV76lrCCCac-z8BnkjyHC-4AwpVA";
    private static String stableAccessToken;
    private static long expireTime;
    private static final Object lock = new Object();

    public static String getStableAccessToken(String appId, String appSecret) throws Exception {
        return getStableAccessToken(appId, appSecret, false);
    }

    public static String getStableAccessToken(String appId, String appSecret, boolean forceRefresh) throws Exception {
        synchronized (lock) {
            if (forceRefresh || System.currentTimeMillis() + 5 * 60 * 1000 > expireTime || stableAccessToken == null) {
                refreshStableAccessToken(appId, appSecret);
            }
            return stableAccessToken;
        }
    }

    private static void refreshStableAccessToken(String appId, String appSecret) throws Exception {
        System.out.println("开始刷新稳定版access_token...");
        long startTime = System.currentTimeMillis();

        String url = "https://api.weixin.qq.com/cgi-bin/stable_token";
        String requestBody = String.format("{\"appid\":\"%s\",\"secret\":\"%s\",\"grant_type\":\"client_credential\",\"force_refresh\":false}",
                appId, appSecret);

        HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        try (java.io.OutputStream os = con.getOutputStream()) {
            byte[] input = requestBody.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            try (BufferedReader br = new BufferedReader(
                    new InputStreamReader(con.getErrorStream(), "utf-8"))) {
                StringBuilder errorResponse = new StringBuilder();
                String errorLine;
                while ((errorLine = br.readLine()) != null) {
                    errorResponse.append(errorLine.trim());
                }
                throw new Exception("HTTP请求失败: " + responseCode + ", 响应: " + errorResponse.toString());
            }
        }

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(con.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            JSONObject json = JSONObject.parseObject(response.toString());

            if (json.containsKey("errcode") && json.getIntValue("errcode") != 0) {
                throw new Exception("获取稳定access_token失败: " + json);
            }

            stableAccessToken = json.getString("access_token");
            expireTime = System.currentTimeMillis() + json.getLongValue("expires_in") * 1000;

            System.out.println("成功获取稳定版access_token，耗时: " +
                    (System.currentTimeMillis() - startTime) + "ms");
            System.out.println("新token过期时间: " + new Date(expireTime));
        }
    }
    public static String getAccessToken() {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + APPSECRET;
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.containsKey("access_token")) {
                return jsonObject.getString("access_token");
            } else {
                System.out.println("获取 Access Token 失败: " + result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getStableAccessToken(boolean b) {
        String url = "https://api.weixin.qq.com/cgi-bin/stable_token";
        String body = "{\"appid\":\"wxc1988ee4eea27c09\",\"secret\":\"7e2cdb5251dbc6cfe6696bb30a6070e8\",\"grant_type\":\"client_credential\",\"force_refresh\":"+ b +"}";
        try {
            HttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            StringEntity entity = new StringEntity(body.toString(), "UTF-8");
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-Type", "application/json");
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            String result = EntityUtils.toString(responseEntity);
            JSONObject jsonResult = JSONObject.parseObject(result);
            String res = jsonResult.getString("access_token");
            if (res.contains("\"errcode\":40001")) {
                // 刷新 access_token 并重试
                return getStableAccessToken(true);
            }
            return res;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String getTemplateList(String accessToken) {
        String url = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=" + accessToken;
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            log.info("获取的模版：" + EntityUtils.toString(entity));
            return EntityUtils.toString(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 发送 消息推送
    public static void sendTemplateMessage(String accessToken, String openid, String studentName, String examName,
                                           String wxPagePath, String time, String subject) {
        // 使用公众号模板消息接口
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        try {
            JSONObject data = new JSONObject();
            JSONObject thing1 = new JSONObject();
            thing1.put("value", examName);
            JSONObject time4 = new JSONObject();
            time4.put("value", time);
            JSONObject thing6 = new JSONObject();
            thing6.put("value", subject);
            JSONObject thing10 = new JSONObject();
            thing10.put("value", studentName);
            data.put("thing1", thing1);
            data.put("time4", time4);
            data.put("thing6", thing6);
            data.put("thing10", thing10);
            JSONObject requestBody = new JSONObject();
            //设置跳转小程序
            JSONObject miniProgram = new JSONObject();
            miniProgram.put("appid", "wx386fff798b03e527");
            miniProgram.put("pagepath", wxPagePath);
            requestBody.put("touser", openid);
            requestBody.put("template_id", TEMPLATE_ID);
            requestBody.put("data", data);
            requestBody.put("miniprogram", miniProgram);
            StringEntity entity = new StringEntity(requestBody.toString(), "UTF-8");
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-Type", "application/json");

            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            String result = EntityUtils.toString(responseEntity);
            JSONObject jsonResult = JSONObject.parseObject(result);

            System.out.println("请求数据：" + requestBody.toString());
            System.out.println("响应结果：" + result);

            if (jsonResult.getIntValue("errcode") == 0) {
                System.out.println("模板消息发送成功");
            } else {
                System.out.println("模板消息发送失败");
                System.out.println("错误码: " + jsonResult.getIntValue("errcode"));
                System.out.println("错误信息: " + jsonResult.getString("errmsg"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static boolean checkUserSubscription(String accessToken, String openId) {
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN";
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            JSONObject jsonObject = JSONObject.parseObject(result);

            System.out.println("用户信息：" + result);

            // subscribe=1 表示已关注，subscribe=0 表示未关注
            return jsonObject.getIntValue("subscribe") == 1;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
    //发送 订阅消息
    public static void send(String accessToken, String openId, String templateId) {
        try {
            String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/json");
            con.setDoOutput(true);
            JSONObject data = new JSONObject();
            data.put("touser", openId);
            data.put("template_id", templateId);
            data.put("page", "index"); // 点击消息跳转小程序页面，若无则填默认值
            // 设置消息内容，根据模板定义的关键词填充
            JSONObject thing7 = new JSONObject();
            thing7.put("value", "备注");
            JSONObject time6 = new JSONObject();
            time6.put("value", "2025-05-08");
            JSONObject thing5 = new JSONObject();
            thing5.put("value", "测试作业1");
            JSONObject date4 = new JSONObject();
            date4.put("value", "2025-05-09");
            JSONObject dataObj = new JSONObject();
            dataObj.put("thing7", thing7);
            dataObj.put("time6", time6);
            dataObj.put("thing5", thing5);
            dataObj.put("date4", date4);
            data.put("data", dataObj);
            OutputStream os = con.getOutputStream();
            os.write(data.toString().getBytes());
            os.flush();
            os.close();
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            System.out.println("发送结果：" + response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取用户列表
    public static String getWxUserList(String accessToken) {
        String url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken +"&next_openid=";
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JSONObject jsonObjectString = JSONObject.parseObject(jsonObject.getString("data"));
            String openIds = jsonObjectString.getString("openid");
            // subscribe=1 表示已关注，subscribe=0 表示未关注
            return openIds;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    //获取用户基本信息
    public static String getUserInfo(String accessToken, String openid) throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("GET");

        int responseCode = con.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            return response.toString();
        } else {
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getErrorStream()));
            StringBuilder errorResponse = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                errorResponse.append(inputLine);
            }
            in.close();
            throw new Exception("请求失败，响应码: " + responseCode + "，错误信息: " + errorResponse.toString());
        }
    }

    public static void main(String[] args) throws Exception {
        String accessToken = getStableAccessToken(APPID, APPSECRET);
        String result = getWxUserList(accessToken);
        List<String> openIds = JSON.parseArray(result, String.class);
        for(int i=0;i<openIds.size();i++) {
            String userInfo = getUserInfo(accessToken, openIds.get(i));
            log.info("第"+ i +"个用户：" + userInfo);
        }
        //getTemplateList(accessToken);
        //send(accessToken, OPENID, TEMPLATE_ID);
//        if (checkUserSubscription(accessToken, OPENID)) {
//            System.out.println("用户已关注公众号，尝试发送消息");
//            sendTemplateMessage(accessToken, OPENID, "测试学生", "测试作业试卷");
//        } else {
//            System.out.println("用户未关注公众号或已取消关注，无法发送消息");
//        }
    }
}
